package org.easy.socket.server;

import org.easy.socket.server.config.ServerConfig;
import org.easy.socket.server.manager.impl.ClientManager;
import org.easy.socket.server.processor.EasyServerMessageProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smartboot.socket.extension.processor.AbstractMessageProcessor;
import org.smartboot.socket.transport.AioQuickServer;

import java.io.IOException;
import java.util.Objects;

/**
 * @Description: 服务端
 * @Author: wxl
 * @CreateTime: 2023/1/10 14:19
 */
public final class EasyServer{

    private static final Logger logger = LoggerFactory.getLogger(EasyServer.class);

    private final ServerConfig serverConfig;

    private boolean startHeart;

    private AioQuickServer server;

    public EasyServer(){
        this(new ServerConfig());
    }

    public EasyServer (ServerConfig serverConfig) {
        this.serverConfig = serverConfig;
        this.initServer();
    }

    public void start() {
        try {
            getServer().start();
            addListener();
        } catch (IOException e) {
            logger.error("启动服务端出现异常:{}",e.getMessage());
        }
    }

    private void initServer() {
        if (Objects.isNull(this.serverConfig.getPort())) {
            getServerConfig().setPort(8000);
        }

        if (Objects.isNull(this.serverConfig.getHost())) {
            getServerConfig().setHost("127.0.0.1");
        }
        this.initAioQuickServer();
    }

    private void initAioQuickServer () {
        AbstractMessageProcessor<String> processor = new EasyServerMessageProcessor(ClientManager.getInstance());
        AioQuickServer aioQuickServer =  new AioQuickServer(getServerConfig().getHost(),getServerConfig().getPort(), (byteBuffer, aioSession) -> {
            int remaining = byteBuffer.remaining();
            if (remaining < Integer.BYTES) {
                return null;
            }
            byteBuffer.mark();
            int length = byteBuffer.getInt();
            if (length > byteBuffer.remaining()) {
                byteBuffer.reset();
                return null;
            }
            byte[] b = new byte[length];
            byteBuffer.get(b);
            byteBuffer.mark();
            return new String(b);
        },processor);
        setServer(aioQuickServer);
    }

    private void addListener () {

    }

    public AioQuickServer getServer() {
        return server;
    }

    public void setServer(AioQuickServer server) {
        this.server = server;
    }

    public boolean isStartHeart() {
        return startHeart;
    }

    public void setStartHeart(boolean flag) {
        this.startHeart = flag;
    }

    public ServerConfig getServerConfig() {
        return serverConfig;
    }
}
